package edu.bit.water.service;


import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import edu.bit.water.dao.MetaSensorDao;
import edu.bit.water.entity.MetaSensor;
import  edu.bit.water.service.MetaSensorService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
//import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

import edu.bit.water.dao.ChartDao;
import edu.bit.water.dao.EntitySensorDao;
import edu.bit.water.entity.Chart;
import edu.bit.water.entity.Column;

/**
 * 流出图业务层
 * @author HJS
 *
 */
@Service
public class ChartService {

	@Autowired
	ChartDao chartDao;
	@Autowired
	MetaSensorDao metaSensorDao;
	@Autowired
	MetaSensorService metaSensorService;
	@Autowired
	private EntitySensorDao entitySensorDao;
	/**
	 * 增加流程图相关数据的方法
	 * @param chart 流程图实体类
	 * @return 成功返回1,失败返回0
	 */
	public Map<String, String> addChart(Chart chart){
		Map<String, String> map = new HashMap<>();
		Integer id = chartDao.getMaxId();
		if(id == null) {
			chart.setId(0);
		}else {
			chart.setId(id + 1);
		}
//		//首先根据流程名称查询是否有重复的
//		Chart chartTmep = chartDao.selectByName(chart.getChartName());
//		if (null !=chartTmep) {
//			String d1 = chart.getData();
//			String d2 = chartTmep.getData();
//			if (d1 == d2){
//				map.put("status", "failed");
//				map.put("msg", "流程图名称已存在，请重新输入");
//				return map;
//			}
//			else {
//				chart.setId(chartTmep.getId());
//				return updateChart(chart);
//			}
//		}
//		else {
//			//否则还是插入操作
//			int n = chartDao.addChart(chart);
//			if (n == 1) {
//				map.put("status", "success");
//				return map;
//			}
//			else {
//				map.put("status", "failed");
//			}
//		}
//		int n = chartDao.addChart(chart);
//		if (n == 1) {
//			map.put("status", "success");
//			return map;
//		}
//		else {
//			map.put("status", "failed");
//		}
		try{
			chartDao.addChart(chart);
			map.put("status", "success");
		}catch (DuplicateKeyException e){
			map=updateChart(chart);
		}
		return map;
	}

	/**
	 * 删除流程图的方法
	 * @param idList 将要被删除id的list集合
	 * @return 成功返回1,失败返回0
	 */
	public int deleteChart(List<Integer> idList) {
		try {
			for (int id : idList) {
				chartDao.deleteChart(id);
			}
			return 1;
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
			return 0;
		}
	}

	/**
	 * 修改某个流程图数据
	 * @param chart 将要被修改的流程图数据
	 * @return 成功返回1,失败返回0
	 */
	public Map<String, String> updateChart(Chart chart) {
		Map<String, String> map = new HashMap<>();
		try {
			int n = chartDao.updateChart(chart);
			if (n == 1) {
				map.put("status", "success");
			}
			else {
				map.put("status", "failed");
			}
			return map;
		}catch(DuplicateKeyException e) {
			if (e.getMessage().indexOf("CHART_UNIQUE") != -1) {
				map.put("status", "failed");
				map.put("msg", "流程图名称已存在，请重新输入");
				return map;
			}
		}
		return map;
	}
	/**
	 * 查询所有流程图数据的方法
	 * @return 成功返回Chart集合,失败返回NULL
	 */
	public List<Chart> selectChart() {
		return chartDao.selectChart();
	}


	public List<Chart> selectChartByBusiness(int businessId) {return chartDao.selectChartByBusiness(businessId);}

	/**
	 * 查询某个流程图数据的方法
	 * @return 成功返回Chart实体,失败返回NULL
	 */
	public Chart selectOne(int id) {
		return chartDao.selectOne(id);
	}
	/**
	 * @param name 水信息表中的传感器名称
	 * @return 返回以时间为标准的最新记录
	 */
	public Map<String, Object> selectWater(String name){
		//List<Column> list = chartDao.waterNameMatch();
		Map<String, Object> map = chartDao.selectWater(name);
		if (map == null) {
			return null;
		}
		map = replace(map, "CREATED_AT", "创建时间");
		map = replace(map, "SENSOR_ROW_ID", "设备编号");
		map = replace(map, "VALUE", "值");
		return map;

	}
	/**获取设备传感器信息的方法
	 * @return 设备传感器信息
	 */
	//返回设备元数据表中的英文字段名和中文字段名
	public List<Map<String, Object>> sensorNameMatch(int company_id){
		//集合list1为设备实体表对应的记录
		List<Map<String, Object>> list1 = entitySensorDao.selectEntitySensor("" + company_id);
		//集合list2为设备元数据表中字段的英文名和中文名
		List<Column> list2 =  chartDao.sensorNameMatch();
		String code1 = metaSensorService.getCodeByCSName("准确度等级");
		String code2 = metaSensorService.getCodeByCSName("型号规格");
		String code3 = metaSensorService.getCodeByCSName("测量范围(t/h)");
		String code4 = metaSensorService.getCodeByCSName("生产厂家");
		String code5 = metaSensorService.getCodeByCSName("出厂编号");
		String code6 = metaSensorService.getCodeByCSName("状态（合格在用/停用）");
		String code7 = metaSensorService.getCodeByCSName("设备成色");
		//遍历list2集合
		for(Map<String, Object> map:list1) {
			for(Column column:list2) {
				//如果集合map1中包含元数据中的key值，则将此键值对换成键为中文名的键值对
				//此处条件必须先把enName变成大写
				if (map.containsKey(column.getEnName().toUpperCase())) {
					Object value = map.get(column.getEnName().toUpperCase());
					map.remove(column.getEnName().toUpperCase());
					if(value != null)
						map.put(column.getCsName(), value);
				}
				/*//如果集合map1中不包含元数据中的key值,则将空值插入
				else {
					map.put(column.getCsName(), null);
				}*/
			}
			map = replace(map, code4, "单位");
			map = replace(map, code5, "出厂编号");
			map = replace(map, code6, "状态（合格在用/停用）");
			map = replace(map, code7, "设备成色");
			map = replace(map, "SENSOR_ROW_ID", "设备编号");
			map = replace(map, "SORT", "设备类名");
			map = replace(map, "NAME", "名称");
			map = replace(map, "ID", "标识符");
			map = replace(map, code1, "水表精度");
			map = replace(map, code2, "水表型号");
			map = replace(map, code3, "计量范围");

		}
		return list1;
	}
	//代替固有字段的方法
	public Map<String, Object> replace(Map<String, Object> map,String string,String csString){
		Object value = map.get(string);
		map.remove(string);
		map.put(csString, value);
		return map;
	}
	/**
	 * @return 从设备元数据表中返回所有属性值 
	 */
	public List<String> WatercsName(){
		List<Column> list = chartDao.waterNameMatch();
		List<String> csNameLists = new ArrayList<>();
		for(Column column:list) {
			csNameLists.add(column.getCsName());
		}
		return csNameLists;
	}
	/**
	 * @param id propertyList
	 * @return 返回水信息
	 */
	public List<Map<String, Object>> selectByProperty(int id,List<String> propertyList){
		List<Column> list = chartDao.waterNameMatch();
		List<String> selectWanted = new ArrayList<>();
		List<String> sensorNameList = findSensorName(id);
		selectWanted.add("sensor_name");
		for(String string : propertyList) {
			for (Column column : list) {
				if (column.getCsName().equals(string)) {
					selectWanted.add(column.getEnName().toLowerCase());
					break;
				}
			}
		}
		String string = selectWanted.toString();
		String selectString = string.substring(1, string.length()-1);
		Map<String, Object> map = new HashMap<>();
		List<Map<String, Object>> listResult = new ArrayList<>();
		for(int i = 0;i < sensorNameList.size();i++) {
			map.put("sql", selectString);
			map.put("sensor_name","'"+sensorNameList.get(i)+"'");
			listResult.add(chartDao.selectByProperty(map));
		}
		for(Map<String, Object> map1:listResult) {
			Object sensorName = map1.get("SENSOR_NAME");
			map1.remove("SENSOR_NAME");
			map1.put("设备名称", sensorName);
			for(Column column:list) {
				//如果集合map1中包含元数据中的key值，则将此键值对换成键为中文名的键值对
				//此处条件必须先把enName变成大写
				if (map1.containsKey(column.getEnName().toUpperCase())) {
					Object value = map1.get(column.getEnName().toUpperCase());
					map1.remove(column.getEnName().toUpperCase());
					map1.put(column.getCsName(), value);
				}
				/*//如果集合map1中不包含元数据中的key值,则将空值插入
				else {
					map.put(column.getCsName(), null);
				}*/
			}
		}
		for(Map<String, Object> map1:listResult) {
			for(String string1 : propertyList) {
				if(!map1.keySet().contains(string1))
					map1.put(string1, 0);
			}
		}
		return listResult;
	}
	/**
	 * 根据流程图表中的id标识符查询data字段中包含哪些设备
	 * @param id 标识符
	 * @return 设备集合
	 */
	public List<String> findSensorName(int id){
		List<String> list = new ArrayList<>();
		Chart chart = chartDao.selectOne(id);
//		System.out.println(chart.getData());
		JSONObject jsonObject = JSONObject.parseObject(chart.getData());
		JSONArray jsonArray = (JSONArray) jsonObject.get("nodeDataArray");
		for (int i = 0; i < jsonArray.size(); i++) {
			JSONObject jsonObjectTemp = jsonArray.getJSONObject(i);
			String name = jsonObjectTemp.getString("name");
			if (name != null) {
				list.add(name);
			}
		}
		return list;
	}

	/*
	根据企业查询所有所在id
	 */
	public Map<String, Object> queryLocationByBusinessId(String businessId) {
		List<String> list = chartDao.queryLocationByBusinessId(businessId);
		Map<String, Object> map = new HashMap<>();
		map.put("status", "success");
		map.put("data", list);
		return map;
	}

	/*
	根据企业查询所有所在id
	 */
	public Map<String, Object> querySensorTypeByLocation(String businessId, String location) {
		List<String> list = chartDao.querySensorTypeByLocation(businessId, location);
		Map<String, Object> map = new HashMap<>();
		map.put("status", "success");
		map.put("data", list);
		return map;
	}


	/*
	根据企业查询所有所在id
	 */
	public Map<String, Object> querySensorIdByLocationAndType(String businessId, String location, String sensorType) {
		List<String> list = chartDao.querySensorIdByLocationAndType(businessId, location, sensorType);
		Map<String, Object> map = new HashMap<>();
		map.put("status", "success");
		map.put("data", list);
		return map;
	}
		/*
	根据企业查询所有设备名称
	 */
	public Map<String, Object> querySensorNameByBusinessId(String businessId) {
		List<String> list = chartDao.querySensorNameByBusinessId(businessId);
		Map<String, Object> map = new HashMap<>();
		map.put("status", "success");
		map.put("data", list);
		return map;
	}

	/*
根据名称查询所有设备类型
 */
	public Map<String, Object> querySensorNoByName(String businessId,String name) {
		List<String> list = chartDao.querySensorNoByName(businessId,name);
		Map<String, Object> map = new HashMap<>();
		map.put("status", "success");
		map.put("data", list);
		return map;
	}

	/**获取设备传感器信息的方法
	 * @return 设备传感器信息
	 */
	//返回设备元数据表中的英文字段名和中文字段名
	public List<Map<String, Object>> sensorNameMatchBySensorId(String businessId,String sensor_row_id){
		//集合list1为设备实体表对应的记录
		List<Map<String, Object>> list1 = entitySensorDao. selectEntitySensorBySensorId(businessId,sensor_row_id);
		//集合list2为设备元数据表中字段的英文名和中文名
		List<Column> list2 =  chartDao.sensorNameMatch();
		String code1 = metaSensorService.getCodeByCSName("准确度等级");
		String code2 = metaSensorService.getCodeByCSName("型号规格");
		String code3 = metaSensorService.getCodeByCSName("测量范围(t/h)");
		String code4 = metaSensorService.getCodeByCSName("生产厂家");
		String code5 = metaSensorService.getCodeByCSName("出厂编号");
		String code6 = metaSensorService.getCodeByCSName("状态（合格在用/停用）");
		String code7 = metaSensorService.getCodeByCSName("设备成色");
		//遍历list2集合
		for(Map<String, Object> map:list1) {
			for(Column column:list2) {
				//如果集合map1中包含元数据中的key值，则将此键值对换成键为中文名的键值对
				//此处条件必须先把enName变成大写
				if (map.containsKey(column.getEnName().toUpperCase())) {
					Object value = map.get(column.getEnName().toUpperCase());
					map.remove(column.getEnName().toUpperCase());
					if(value != null)
						map.put(column.getCsName(), value);
				}
				/*//如果集合map1中不包含元数据中的key值,则将空值插入
				else {
					map.put(column.getCsName(), null);
				}*/
			}
			map = replace(map, code4, "单位");
			map = replace(map, code5, "出厂编号");
			map = replace(map, code6, "状态（合格在用/停用）");
			map = replace(map, code7, "设备成色");
			map = replace(map, "SENSOR_ROW_ID", "设备编号");
			map = replace(map, "SORT", "设备类名");
			map = replace(map, "NAME", "名称");
			map = replace(map, "ID", "标识符");
			map = replace(map, code1, "水表精度");
			map = replace(map, code2, "水表型号");
			map = replace(map, code3, "计量范围");

		}
		return list1;
	}
}
